package main

import (
	"GLibHac/hac"
	"GLibHac/nsfs"
	"fmt"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	"io/fs"
	"log"
	"os"
	"os/user"
	"path/filepath"
)

var keySetPath string
var rootCmd = &cobra.Command{
	Run: func(cmd *cobra.Command, args []string) {
		keySet := nsfs.NewDefaultKeySet()
		err := nsfs.ReloadKeySetFromFile(keySet, keySetPath)
		if err != nil {
			log.Fatalf("failed to load key set: %v", err)
		}
		if len(args) == 0 {
			workDir, err := os.Getwd()
			if err != nil {
				log.Fatalf("failed to get current working directory: %v", err)
			}
			showDirDetails(workDir, keySet)
		} else {
			for _, p := range args {
				stat, err := os.Stat(p)
				if err != nil {
					log.Fatalf("failed to stat %s: %v", p, err)
				} else if stat.IsDir() {
					showDirDetails(p, keySet)
				} else {
					showFileDetails(p, keySet)
				}
			}
		}
	},
}

func showFileDetails(file string, keySet *nsfs.KeySet) {
	information, err := hac.LoadApplication(keySet, file)
	if err != nil {
		if !errors.Is(err, hac.UnsupportedFileType) {
			log.Printf("failed to load file %s: %v\n", file, err)
		}
	} else {
		fmt.Printf("File -> %s:\n", file)
		fmt.Printf("\tTitleInfos:\n")
		for _, v := range information.TitleInfos {
			fmt.Printf("\t\tName: \"%s\"\tLanguage: %s\tPublisher: %s\n", v.Name, v.Language, v.Publisher)
		}
		fmt.Printf("\tTitleName: %s\n", information.TitleName)
		fmt.Printf("\tVersion: %s\n", information.Version)
		fmt.Printf("\tTitleId: %s\n", information.TitleId)
		fmt.Printf("\tTitleVersion: %s\n", information.TitleVersion)
		fmt.Printf("\tMetaTitleId: %s\n", information.MetaTitleId)
		fmt.Printf("\tContentMetaType: %s\n", information.ContentMetaType)
		fmt.Printf("\tMinimumSystemVersion: %s\n", information.MinimumSystemVersion)
		fmt.Printf("\tMinimumApplicationVersion: %s\n", information.MinimumApplicationVersion)
	}
}

func showDirDetails(dirPath string, keySet *nsfs.KeySet) {
	err := filepath.Walk(dirPath, func(path string, info fs.FileInfo, err error) error {
		showFileDetails(path, keySet)
		return nil
	})
	if err != nil {
		log.Fatalf("failed to walk dir %s: %v", dirPath, err)
	}
}

func main() {
	current, err := user.Current()
	if err != nil {
		log.Fatalf("failed to get current user: %v", err)
	}
	rootCmd.PersistentFlags().StringVar(&keySetPath, "k", filepath.Join(current.HomeDir, ".switch/prod.keys"), "switch prod.keys position")
	rootCmd.PersistentFlags()
	cobra.CheckErr(rootCmd.Execute())
}
